package com.apobates.forum.member.impl;

import com.apobates.forum.event.elderly.ForumActionEnum;
import com.apobates.forum.event.elderly.IpLocation;
import com.apobates.forum.event.elderly.MemberActionDescriptor;
import com.apobates.forum.member.entity.Member;
import com.apobates.forum.member.entity.MemberActiveRecords;
import com.apobates.forum.member.service.MemberActiveRecordsService;
import java.util.Optional;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.CodeSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Member模块中关于MemberAction注解拦截器
 *
 * @author xiaofanku
 * @since 20200529
 */
@Aspect
public class MemberActionAspect {
    @Autowired
    private MemberActiveRecordsService memberActiveRecordsService;
    private final static Logger logger = LoggerFactory.getLogger(MemberActionAspect.class);
    
    @AfterReturning(pointcut = "@annotation(memberAction) && args(.., actionDescriptor)", returning = "retVal")
    public void check(
            JoinPoint joinPoint,
            MemberAction memberAction,
            MemberActionDescriptor actionDescriptor,
            Object retVal) throws Throwable {
        //
        Object[] paramValues = joinPoint.getArgs();
        CodeSignature signature = (CodeSignature) joinPoint.getStaticPart().getSignature();
        ForumActionEnum action = memberAction.action();
        String masterArgName = memberAction.keyName();
        Class<?> masterArgType = memberAction.keyType();
        logger.info(String.format("[MAT]arg name: %s, arg Type: %s, action: %s", masterArgName, masterArgType, action.getTitle()));
        // 返回值
        Optional<?> data;
        boolean status = false;
        try {
            data = (Optional) retVal;
        } catch (ClassCastException e) {
            return;
        }
        if (data.isPresent()) { // 执行失败的
            status = true;
        }
        
        Long memberId = 0L;
        String names = Member.GUEST_NAMES;
        //
        String[] methodArguNames = signature.getParameterNames();
        for (int i = 0; i < paramValues.length; i++) {
            //logger.info(String.format("[MAT]method arg name: %s, method param Value: %s", methodArguNames[i], paramValues[i]));
            if (masterArgName.equals(methodArguNames[i])) {
                if (masterArgType == Long.class) {
                    memberId = (Long) paramValues[i];
                } else if (masterArgType == String.class) {
                    names = (String) paramValues[i];
                }
            }
        }
        //
        if (memberId > 0 && Member.GUEST_NAMES == names) {
            //取到names
            names = "*";
        }
        //
        IpLocation location = actionDescriptor.location();
        logger.info(String.format("[MAT]Agent: %s, Device: %s, Ip Address: %s", actionDescriptor.getAgent(), actionDescriptor.getDevice(), location.getIpAddr()));
        MemberActiveRecords mar = new MemberActiveRecords(
                action,
                status,
                memberId,
                names,
                location.getIpAddr(),
                actionDescriptor.getReferrer(),
                actionDescriptor.getToken(),
                actionDescriptor.getDevice(),
                actionDescriptor.getAgent());
        
        mar.setIsp(location.getIsp());
        mar.setProvince(location.getProvince());
        mar.setDistrict(location.getDistrict());
        mar.setCity(location.getCity());
        
        memberActiveRecordsService.create(mar);
    }
}